﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Grundy.Common;

namespace Grundy.Message
{
    
    [DataContract]
    public class LicenseClientType
    {  
        [DataMember]
        public string Name { get; set; }

        private List<Type> _identifiers;
        
        public IEnumerable<Type> GetIdentifiers()
        {
            return _identifiers;
        }

        protected int Specificity = 0;

        public bool Equals(LicenseClientType other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Equals(other.Name, Name);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (LicenseClientType)) return false;
            return Equals((LicenseClientType) obj);
        }

        public override int GetHashCode()
        {
            return (Name != null ? Name.GetHashCode() : 0);
        }

        public static bool operator ==(LicenseClientType left, LicenseClientType right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(LicenseClientType left, LicenseClientType right)
        {
            return !Equals(left, right);
        }

        public bool IsNull()
        {
            return Name.IsNullOrEmpty();
        }

        public static LicenseClientType Checkout
        {
            get
            {
                return new LicenseClientType
                           {
                               Name = "Checkout", 
                               _identifiers = new []
                                                 {
                                                     typeof(CheckoutIdentifier),
                                                     typeof(UserNameIdentifier),
                                                     typeof(UserSidIdentifier),
                                                     typeof(ProcessorIdentifier),
                                                     typeof(BiosIdentifier),
                                                     typeof(MacAddressIdentifier),
                                                     typeof(ProcessIdentifier),
                                                     typeof(HostnameIdentifier),
                                                     typeof(UserNameIdentifier),
                                                     typeof(UserSidIdentifier),
                                                     typeof(TerminalServicesIdentifier)
                                                 }.ToList(),
                               Specificity = 5
                           };
            }
        }

        public static LicenseClientType Machine
        {
            get
            {
                return new LicenseClientType
                {
                    Name = "Machine",
                    _identifiers = new[]
                                                 {
                                                     typeof(ProcessorIdentifier),
                                                     typeof(BiosIdentifier)
                                                 }.ToList(),
                    Specificity = 1
                };
            }
        }

        public static LicenseClientType Process
        {
            get
            {
                return new LicenseClientType
                {
                    Name = "Process",
                    _identifiers = new[]
                                                 {
                                                     typeof(ProcessorIdentifier),
                                                     typeof(BiosIdentifier),
                                                     typeof(ProcessIdentifier)
                                                 }.ToList(),
                    Specificity = 2
                };
            }
        }

        public static LicenseClientType TerminalServicesSession
        {
            get
            {
                return new LicenseClientType
                {
                    Name = "TerminalServicesSession",
                    _identifiers = new[]
                                                 {
                                                     typeof(ProcessorIdentifier),
                                                     typeof(BiosIdentifier),
                                                     typeof(TerminalServicesIdentifier)
                                                 }.ToList(),
                    Specificity = 3
                };
            }
        }

        public static LicenseClientType User
        {
            get
            {
                return new LicenseClientType
                {
                    Name = "User",
                    _identifiers = new[]
                                                 {
                                                     typeof(UserNameIdentifier),
                                                     typeof(UserSidIdentifier),
                                                     typeof(ProcessorIdentifier),
                                                     typeof(BiosIdentifier),
                                                     typeof(MacAddressIdentifier),
                                                     typeof(ProcessIdentifier),
                                                     typeof(HostnameIdentifier),
                                                     typeof(UserNameIdentifier),
                                                     typeof(UserSidIdentifier),
                                                     typeof(TerminalServicesIdentifier)
                                                 }.ToList(),
                    Specificity = 4
                };
            }
        }
        
        public static LicenseClientType Parse(string s)
        {
            if (s.IsNullOrEmpty())
                return null;
            var type = s.ToUpperInvariant();
            switch (type)
            {
                case "CHECKOUT": 
                    return Checkout;
                case "MACHINE":
                    return Machine;
                case "PROCESS":
                    return Process;
                case "TERMINALSERVICESSESSION":
                    return TerminalServicesSession;
                case "USER":
                    return User;
                default:
                    return null;
            }
        }

        public override string ToString()
        {
            return Name;
        }
    }
}